home *** CD-ROM | disk | FTP | other *** search
- {
- I have just extended some PD sources (in this month's SWAG - HOOKCRT.PAS) to
- convert it to a unit, with supporting Pascal Object and Delphi Class. This
- hooks into the WinCRT unit (BPW and Delphi 1.x) to add menus, etc. A sample
- program is included. You might wish to add this to the SWAG archives.
- Thanks.
-
- ------------------------------ cut ------------------------------ }
- Unit HookCrt2;
-
- { ----- ORIGINAL MESSAGE ---
- The intent of this program is to provide the ability to add additional functionality
- to WinCRT. Like the ablity to add and use a menubar and to be able to respond to
- mouse clicks.
-
- WinCRT does NOT need to be modified to run this app.
-
- This program is Public Domain by Cedar Island Software. Use it as you see fit.
- All the usual disclaimers apply.
-
- Thanks to Neil Rubenking and his book 'Turbo Pascal for Windows Techniques and Utilities'.
- Thanks to Kurt Barthlemess of BPASCAL (TeamB).
- Thanks also to Paul A. LeBlanc of BCPPWIN (TeamB).
-
-
- Good Luck and Have Fun.
- Mike Caughran
- Cedar Island Software
- [71034,2371]
-
- ---- ADDED MESSAGE by Dr A Olowofoyeku ------
- September 1996
- Amended and Extended by Dr A Olowofoyeku (The African Chief);
- [a] converted to a unit
- [b] a Pascal object (and Delphi Class) to encapsulate the
- unit's functionality.
- [c] some default procedural types and functions
- [d] MyInitWinCRT changed to: HookedInitWinCRT - and now
- takes some parameters
- [e] MyDoneWinCRT changed to: HookedDoneWinCrt;
- [f] supports Delphi 1.x
-
- Enjoy!
-
- THIS UNIT IS PUBLIC DOMAIN -
- NOTHING IS WARRANTEED. USE AT YOUR OWN RISK!
-
- Dr A. Olowofoyeku (The African Chief)
- Email: laa12@cc.keele.ac.uk
- http://ourworld.compuserve.com/homepages/African_Chief/
- }
-
- Interface
- {$ifdef Ver80} {Delphi 1.x}
- {$Define Delphi}
- {$endif Ver80}
-
- uses {$ifndef Delphi}Objects {$else}Messages{$endif},WinCRT, WinTypes, WinProcs;
-
- {/////////////////////////////////////////////////////////////}
- {////////////// exported data and functions //////////////////}
- {/////////////////////////////////////////////////////////////}
- {custom icon for CRT window}
- Var
- CrtappIcon : hIcon;
-
- { User menu command tags (identifiers)
- start from 1 to 64 for CRT menu tags
- }
- Const
- cm_User1 = 1;
- cm_UserMax = 64;
-
- {Crt Window function type}
- Type
- aWindowFunc = Function(Window : HWnd; Message : Word;
- wParam : Word; lParam : LongInt) : LongInt;
-
- {menu command procedural type}
- aMenuFunc = Procedure(Const aTag:integer);
-
-
- {create a CRT window}
- Function HookedInitWinCRT(
- Const
- Left, {left side of the window}
- Top, {top of the window}
- width, {width of the window}
- height:integer; {height of the window}
- Title :pChar ; {window title}
- aWinProc:aWindowFunc; {new window function, or Nil for default}
- MenuFunc:aMenuFunc {new window procedure, or Nil for default}
- ):HWnd; {returns the handle to the CRT window}
-
- {destroy a CRT window}
- Function HookedDoneWinCRT : Boolean;
-
- {/////////////////////////////////////////////////////////////}
- {///////////////////// CRT object ////////////////////////////}
- {// This object encapsulates the functionality of this unit //}
- {/////////////////////////////////////////////////////////////}
- {/////////////////////////////////////////////////////////////}
- Type
- TNewCrtClass = {$ifdef Delphi}Class{$else}Object(TObject){$endif}
- HWindow : HWnd; {handle of the CRT window}
-
- Constructor {$ifdef Delphi}Create{$else}Init{$endif}
- {init constructor - calls HookedInitWinCRT with all these
- parameters, to create the CRT window}
- (Const
- Left, {left side of the window}
- Top, {top of the window}
- width, {width of the window}
- height:integer; {height of the window}
- Title :pChar ; {window title}
- aWinProc:aWindowFunc; {new window function, or Nil for default}
- MenuFunc:aMenuFunc {new window procedure, or Nil for default}
- );
-
- Destructor {$ifDef Delphi}Destroy;override{$else}Done; virtual{$endif};
-
- Procedure MakeMainMenu(Caption:pChar;Tag:integer);virtual;
- {create a main menu item = e.g., File Menu, Edit, etc.
- Caption = the title of the menu
- Tag = the command tag
- }
-
- Procedure MakeSubMenu(ParentNum:Byte;Caption:pChar;Tag:integer);virtual;
- {create a submenu under the main menu "parentnum"
- ParentNum = the numeric ID of the parent main menu
- Caption = the title of the menu
- Tag = the command tag
- }
- Procedure MakeSeparator(ParentNum:Byte);virtual;
- {create a menu separator under the main menu "parentnum"
- ParentNum = the numeric ID of the parent main menu
- }
-
- Procedure AssignCRTMenu;virtual;
- {assign the menu to the CRT window and repaint the menu;
- MUST be called at some stage - normall AFTER all the menu
- items have been create.}
-
- Private
- MainMenus : Array[0..32] of HMenu; {max 32 main MainMenus}
- MenuCount : Word; {number of main MainMenus created}
- end;{end of CRT object}
- {////////////////////////////////////////////////}
- Var
- OldCRTProc : TFarProc;{pointer to old window function}
- NewCRTHandle : HWND; {handle to CRT window}
-
- implementation
-
- var
- NewCRTProc : TFarProc; {pointer to new window function}
-
- Var
- DefMenuFunc:aMenuFunc;{menu command function}
-
- {////////////////////////////////////////////////}
- function NewDefaultMsgHandler(Window : HWnd; Message : Word;
- {default message handler - if none is specified in call to
- HookedInitWinCRT}
- wParam : Word; lParam : LongInt) : LongInt; export;
- begin
- case Message of
- wm_Command : begin
- case WParam of
- cm_User1 .. cm_UserMax:
- If @DefMenuFunc<> Nil then DefMenuFunc(WParam);
- end;
- end;
- end;
- NewDefaultMsgHandler := CallWindowProc(OldCRTProc, Window, Message, wParam, lParam);
- end;
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- Constructor TNewCrtClass.{$ifdef Delphi}Create{$else}Init{$endif};
- Begin
- Inherited {$ifdef Delphi}Create;{$else}Init;{$endif}
- HWindow := HookedInitWinCrt
- (Left,Top,width,height,Title,aWinProc,MenuFunc);
-
- FillChar(MainMenus, Sizeof(MainMenus), #0);
- MainMenus[0] := CreateMenu;
- MenuCount := 0;
- End;
- {////////////////////////////////////////////////}
- Destructor TNewCrtClass.{$ifDef Delphi}Destroy{$else}Done{$endif};
- Begin
- FillChar(MainMenus, Sizeof(MainMenus), #0);
- MenuCount := 0;
- HWindow := 0;
- HookedDoneWinCRT;
- {$ifdef Delphi}
- Inherited Destroy;
- {$else}
- Inherited Done;
- {$endif}
- End;
- {////////////////////////////////////////////////}
- Procedure TNewCrtClass.MakeMainMenu;
- Begin
- If MenuCount>=32 then Exit;
- If Tag > 0 then AppendMenu(MainMenus[0], mf_Enabled, Tag, Caption)
- else begin
- Inc(MenuCount);
- MainMenus[MenuCount] := CreateMenu;
- AppendMenu(MainMenus[0], mf_PopUp or mf_Enabled, MainMenus[MenuCount], Caption);
- end;
- End;
- {////////////////////////////////////////////////}
- Procedure TNewCrtClass.MakeSubMenu;
- Begin
- If (ParentNum<1) or (ParentNum>32) then exit;
- AppendMenu(MainMenus[ParentNum], mf_Enabled, Tag, Caption);
- End;
- {////////////////////////////////////////////////}
- Procedure TNewCrtClass.MakeSeparator;
- Begin
- If (ParentNum<1) or (ParentNum>32) then exit;
- AppendMenu(MainMenus[ParentNum], mf_Separator,0, '');
- End;
- {////////////////////////////////////////////////}
- Procedure TNewCrtClass.AssignCRTMenu;
- Begin
- SetMenu(HWindow,MainMenus[0]);
- End;
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- function GetCRTWindowHandle: HWnd;
- {return handle to the CRT window}
- begin
- ClrScr; {force active window}
- GetCRTWindowHandle := GetActiveWindow;
- end;
- {////////////////////////////////////////////////}
- Procedure GetScreenResolution(Var aTPoint : TPoint);
- {get the current screen resolution and return it in "T"}
- Var
- HD : HDC;
- Wn : HWnd;
- Begin
- Wn := GetDesktopWindow;
- Hd := GetDC(Wn);
- With aTPoint do begin
- X := GetDeviceCaps(Hd, HorzRes);
- Y := GetDeviceCaps(Hd, VertRes);
- End;
- ReleaseDC(Wn, Hd);
- End;
- {////////////////////////////////////////////////}
- Procedure SetWindowCoordinates;
- {set up CRT window for possible scrolling}
- Var
- aPoint : tpoint;
- aReal : real;
- anInt : integer;
-
- Begin
- GetScreenResolution(aPoint);
-
- With aPoint do
- begin
- aReal := Y /25;
- If y > 768 then aReal := (aReal*13.2) else
- If Y >= 600 then aReal := (aReal*15.8) else
- aReal := (aReal*18.4);
-
- anInt := round(aReal + 25);
- WindowSize.Y := anInt;
-
- If X > 800 then anInt := 11 else anInt := 10;
- WindowSize.X := (ScreenSize.X * anInt);
- end;
- End;
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
-
- Function HookedInitWinCRT;
- {initialise the new crt stuff}
- Begin
- {window location coordinates}
- With WindowOrg do begin
- x := Left;
- y := Top;
- end;
-
- {the size of the CRT window buffer}
- With ScreenSize do begin
- x := Width;
- y := Height;
- end;
-
- {setup the window properly}
- SetWindowCoordinates;
-
- {set window title}
- lStrCpy(WindowTitle, Title);
-
- {call WinCRT.InitWinCRT}
- InitWinCrt;
-
- {get the CRT window handle}
- NewCRTHandle := GetCRTWindowHandle;
- {SetWindowText(NewCRTHandle, Title);}
-
- {save old window proc}
- OldCRTProc := TFarProc(GetWindowLong(NewCRTHandle, gwl_WndProc));
-
- {assign new window proc}
- If @aWinProc<>Nil then
- NewCrtProc := MakeProcInstance(@aWinProc, hInstance)
- else
- NewCrtProc := MakeProcInstance(@NewDefaultMsgHandler, hInstance);
-
- {make it happen!}
- SetWindowLong(NewCRTHandle, gwl_WndProc, LongInt(NewCrtProc));
-
- {assign CRT menu proc}
- If @MenuFunc <> Nil then DefMenuFunc := MenuFunc;
-
- {if custom icon used, assign it}
- If CrtappIcon<>0 then
- SetClassWord(NewCRTHandle, gcw_hIcon, CrtappIcon);
-
- {return handle of CRT window}
- HookedInitWinCRT := NewCRTHandle;
- End;
- {////////////////////////////////////////////////}
- Function HookedDoneWinCRT;
- {dispose of the new crt window}
- begin
- DoneWinCrt; {call WinCRT.DoneWinCrt}
- HookedDoneWinCRT:=True;
-
- {do other stuff}
- CrtappIcon := 0;
- NewCRTHandle:=0;
- FreeProcInstance(NewCrtProc);
- DefMenuFunc := Nil;
- end;
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- {///////// initialisation block /////////////////}
- {////////////////////////////////////////////////}
- begin
- CrtappIcon := 0;
- NewCRTHandle := 0;
- DefMenuFunc := Nil;
- end.
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- {// TEST PROGRAM: shows usage of HOOKCRT2.PAS ///}
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- Program TestCRT;
- {$ifdef Ver80}
- {$Define Delphi}
- {$endif Ver80}
-
- uses {$ifdef Delphi}Messages,{$endif}WinTypes,
- WinProcs, HookCrt2, WinCrt;
-
- {menu constants: start from 1 - to infinity}
- Const
- cm_Exit = 1;
- cm_About = 2;
- cm_Clear = 3;
-
- Var
- TestCrtObj : TNewCrtClass;
-
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- Procedure ExecMenus(Const Tag:Integer);forward;
- {a sample procedure to process menu choices}
-
- function ShellAbout(hwnd:HWND; Title,Text:PChar; icon:HICON):integer; external 'SHELL' index 22;
- {an "About" function}
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- function TestProc(Window : HWnd; Message : Word;
- wParam : Word; lParam : LongInt) : LongInt; export;
- {sample new menu handler}
- begin
- case Message of
- wm_char : begin {MessageBeep(0);} end;
- wm_LButtonDown : MessageBox(NewCrtHandle,'Left button','Mouse',MB_OK);
- wm_Command : begin
- case WParam of
- cm_User1 .. cm_UserMax: ExecMenus(WParam);
- end;
- end;
- end;
-
- {call the old window proc = essential!}
- TestProc := CallWindowProc(OldCRTProc, Window, Message, wParam, lParam);
- end;
- {////////////////////////////////////////////////}
- Procedure ExecMenus(Const Tag:Integer);
- Begin
- Case Tag of
- cm_About:
- ShellAbout(NewCrtHandle,'Hooked CRT#Cedar Island Software & The Chief','Hello World, from the Chief!',
- CrtappIcon);
- cm_Exit:
- TestCrtObj.{$ifDef Delphi}Free{$else}Done{$endif};
- {HookedDoneWinCRT;}
- cm_Clear: begin clrscr; gotoxy(1,1); end;
- End;
- End;
- {////////////////////////////////////////////////}
- procedure DoTest;
- var
- Name : String;
- begin
- LoadString(GetModuleHandle('USER'),514,@Name[1],79);
- Name[0]:=Char(LStrLen(@Name[1]));
- Writeln('Hello ',Name);
- Writeln('Welcome to a Subclassed WinCRT World!');
- readln;
- end;
- {////////////////////////////////////////////////}
- {////////////////////////////////////////////////}
- {//////////// program block ////////////////////}
- begin
- TestCrtObj{$ifdef Delphi}:= TNewCrtClass.Create{$else}.Init{$endif}
- (1,1,80,25,'Chief''s Hooked CRT Window',TestProc,ExecMenus);
-
- With TestCrtObj do begin
- MakeMainMenu('&File ', 0);
- MakeSubMenu(1, '&New', 0);
- MakeSubMenu(1, '&Open...', 0);
- MakeSubMenu(1, '&Save', 0);
- MakeSubMenu(1, 'Save &As ...', 0);
- MakeSeparator(1);
- MakeSubMenu(1,'E&xit', cm_Exit);
-
- MakeMainMenu('&Edit ', 0);
- MakeSubMenu(2,'Cu&t Shift+Del', 0);
- MakeSubMenu(2,'&Copy Ctrl+Ins', 0);
- MakeSubMenu(2, '&Paste Shift+Ins', 0);
- MakeSubMenu(2, 'C&lear Ctrl+Del', cm_Clear);
- MakeSeparator(2);
- MakeSubMenu(2,'E&xit', cm_Exit);
-
- MakeMainMenu('&Help ', 0);
- MakeSubMenu(3,'&Contents Shift+F1', 0);
- MakeSubMenu(3,'&Topic Search', 0);
- MakeSubMenu(3,'&Using Help', 0);
- MakeSeparator(3);
- MakeSubMenu(3,'&About ...', cm_About);
- MakeSeparator(3);
- MakeSubMenu(3,'E&xit', cm_Exit);
-
- AssignCrtMenu; {this MUST be called after creating all menus!!}
-
- DoTest; {call a test procedure}
-
- {dispose of object and CRT window}
- {$ifDef Delphi}Free{$else}Done{$endif};
- end;
- end.
-
-
- [----------------------- end cut ------------------------]
- Warmest regards,
- The Chief
- ---------
- Dr. Abimbola A. Olowofoyeku (The African Chief)
- Keele University, England (and, The Great Elephant)
- Email: laa12@keele.ac.uk or, chief@mep.com
- http://ourworld.compuserve.com/homepages/African_Chief/chief.htm